﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management;
using System.Text;
using WMI.NET.Abstracts;
using WMI.NET.CIM;

namespace WMI.NET.ComputerSystemHardware.NetworkingDevice
{
    /// <summary>
    ///  The Win32_NetworkAdapter class is deprecated. Use the MSFT_NetAdapter class instead. The Win32_NetworkAdapter WMI class represents a network adapter of a computer running a Windows operating system.
    /// Win32_NetworkAdapter only supplies IPv4 data. For more information, see IPv6 and IPv4 Support in WMI.
    /// </summary>
    public class Win32_NetworkAdapter : CIM_NetworkAdapter
    {

        private string _AdapterType;
        private Nullable<UInt16> _AdapterTypeID;
        private string _GUID;
        private Nullable<UInt32> _Index;
        private Nullable<Boolean> _Installed;
        private Nullable<UInt32> _InterfaceIndex;
        private string _MACAddress;
        private string _Manufacturer;
        private Nullable<UInt32> _MaxNumberControlled;
        private string _NetConnectionID;
        private Nullable<UInt16> _NetConnectionStatus;
        private Nullable<Boolean> _NetEnabled;
        private Nullable<Boolean> _PhysicalAdapter;
        private string _ProductName;
        private string _ServiceName;
        private Nullable<DateTimeOffset> _TimeOfLastReset;

        /// <summary>
        /// Network medium in use.
        /// </summary>
        public string AdapterType { get { return _AdapterType; } } //TODO enum

        /// <summary>
        /// Network medium in use. Returns the same information as the AdapterType property, except that the information is in the form of an integer. 
        /// </summary>
        public Nullable<UInt16> AdapterTypeID { get { return _AdapterTypeID; } } //TODO enum

        /// <summary>
        /// Globally unique identifier for the connection.
        /// Windows Server 2003 and Windows XP:  This property is not available. 
        /// </summary>
        public string GUID { get { return _GUID; } }

        /// <summary>
        /// Index number of the network adapter, stored in the system registry.
        /// Example: 0
        /// </summary>
        public Nullable<UInt32> Index { get { return _Index; } }

        /// <summary>
        /// If True, the network adapter is installed in the system.
        /// </summary>
        public Nullable<Boolean> Installed { get { return _Installed; } }

        /// <summary>
        /// Index value that uniquely identifies the local network interface. The value in this property is the same as the value in the InterfaceIndex property in the instance of Win32_IP4RouteTable that represents the network interface in the route table.
        /// Windows XP:  This property is not available. 
        /// </summary>
        public Nullable<UInt32> InterfaceIndex { get { return _InterfaceIndex; } }

        /// <summary>
        /// Media access control address for this network adapter. A MAC address is a unique 48-bit number assigned to the network adapter by the manufacturer. It uniquely identifies this network adapter and is used for mapping TCP/IP network communications.
        /// </summary>
        public string MACAddress { get { return _MACAddress; } }

        /// <summary>
        /// Name of the network adapter's manufacturer.
        /// Example: "3COM"
        /// </summary>
        public string Manufacturer { get { return _Manufacturer; } }

        /// <summary>
        /// Maximum number of directly addressable ports supported by this network adapter. A value of 0 (zero) should be used if the number is unknown.
        /// </summary>
        public Nullable<UInt32> MaxNumberControlled { get { return _MaxNumberControlled; } }

        /// <summary>
        /// Name of the network connection as it appears in the Network Connections Control Panel program.
        /// Windows Server 2003 and Windows XP:  This property is read-only.
        /// </summary>
        public string NetConnectionID { get { return _NetConnectionID; } }

        /// <summary>
        ///  State of the network adapter connection to the network.
        /// Windows XP with SP3 and later:  This property returns a value of 2 for a client that is connected to an authenticated port.
        /// Windows XP with SP2 and earlier:  This property returns a value of 9 for a client that is connected to an authenticated port.
        /// </summary>
        public Nullable<UInt16> NetConnectionStatus { get { return _NetConnectionStatus; } } //TODO enum

        /// <summary>
        /// Indicates whether the adapter is enabled or not. If True, the adapter is enabled. You can enable or disable the NIC by using the Enable and Disable methods.
        /// Windows Server 2003 and Windows XP:  This property is not available. 
        /// </summary>
        public Nullable<Boolean> NetEnabled { get { return _NetEnabled; } }

        /// <summary>
        /// Indicates whether the adapter is a physical or a logical adapter. If True, the adapter is physical.
        /// Windows Server 2003 and Windows XP:  This property is not available. 
        /// </summary>
        public Nullable<Boolean> PhysicalAdapter { get { return _PhysicalAdapter; } }

        /// <summary>
        /// Product name of the network adapter.
        /// Example: "Fast EtherLink XL"
        /// </summary>
        public string ProductName { get { return _ProductName; } }

        /// <summary>
        /// Service name of the network adapter. This name is usually shorter than the full product name.
        /// Example: "Elnkii"
        /// </summary>
        public string ServiceName { get { return _ServiceName; } }

        /// <summary>
        /// Date and time the network adapter was last reset.
        /// </summary>
        public Nullable<DateTimeOffset> TimeOfLastReset { get { return _TimeOfLastReset; } }



        /// <summary>
        /// The Disable method disables the network adapter.
        /// </summary>
        /// <returns></returns>
        public UInt32 Disable() { throw new NotImplementedException(); }

        /// <summary>
        /// The Enable method enables the network adapter.
        /// </summary>
        /// <returns></returns>
        public UInt32 Enable() { throw new NotImplementedException(); }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mbo"></param>
        public Win32_NetworkAdapter(ManagementBaseObject mbo)
            : base(mbo)
        {
            _AdapterType = mbo.GetStringValue("AdapterType");
            _AdapterTypeID = mbo.GetUshortValue("AdapterTypeID");
            _GUID = mbo.GetStringValue("GUID");
            _Index = mbo.GetUIntValue("Index");
            _Installed = mbo.GetBoolValue("Installed");
            _InterfaceIndex = mbo.GetUIntValue("InterfaceIndex");
            _MACAddress = mbo.GetStringValue("MACAddress");
            _Manufacturer = mbo.GetStringValue("Manufacturer");
            _MaxNumberControlled = mbo.GetUIntValue("MaxNumberControlled");
            _NetConnectionID = mbo.GetStringValue("NetConnectionID");
            _NetConnectionStatus = mbo.GetUshortValue("NetConnectionStatus");
            _NetEnabled = mbo.GetBoolValue("NetEnabled");
            _PhysicalAdapter = mbo.GetBoolValue("PhysicalAdapter");
            _ProductName = mbo.GetStringValue("ProductName");
            _ServiceName = mbo.GetStringValue("ServiceName");
            _TimeOfLastReset = mbo.GetDateTimeOffsetValue("TimeOfLastReset", Consts.DateTimeFormat);
        }
    }


    /// <summary>
    /// 
    /// </summary>
    public class GetWin32_NetworkAdapters : Win32Collection<Win32_NetworkAdapter>
    {

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override ReadOnlyCollection<Win32_NetworkAdapter> GetCollection()
        {
            List<Win32_NetworkAdapter> tempCollection = new List<Win32_NetworkAdapter>();

            foreach (var s in searcher.Get())
            {
                Win32_NetworkAdapter tempListItem = new Win32_NetworkAdapter(s);
                tempCollection.Add(tempListItem);
            }

            return tempCollection.AsReadOnly();
        }

        /// <summary>
        /// 
        /// </summary>
        public GetWin32_NetworkAdapters() : base("SELECT * FROM Win32_NetworkAdapter") { }

    }

}
